/*
 * Copyright (c) 2010-2011 Plugger Antonio Begue Ponce. All Rights Reserved.
 *
 * This file is part of Plugger Framework.
 *
 *  Plugger Framework is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version 3 as published by
 *  the Free Software Foundation.
 *
 *  Plugger Framework is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Plugger Framework.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.plugger.data;

import java.util.HashSet;
import java.util.Set;
import org.plugger.util.Cryptography;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * The system configuration object.
 * 
 * @author Antonio Begue
 * @version $Revision: 1.0 $
 *
 * @see     DatabaseType
 * @see     ConnectionStringHelper
 * @see     ConnectionString
 * @see     MapperParameters
 */
public class DataConfiguration {
    private static int databaseVersion;
    private static ConnectionString connectionString = null;
    private static MapperParameters mapperParameters = null;
    private static Set<String> assemblies = null;

    /**
     * configure the system with a xml file.
     *
     * @param document the xml file.
     */
    public void configure(Document document) {
        connectionString = new ConnectionString();
        NodeList nodeList = document.getElementsByTagName("Database");
        String value = "";
        
        value = ((Element) nodeList.item(0)).getElementsByTagName("dbType").item(0).getTextContent();
        connectionString.setDatabaseType(DatabaseType.valueOf(value));
        value = ((Element) nodeList.item(0)).getElementsByTagName("Username").item(0).getTextContent();
        connectionString.setUser(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Password").item(0).getTextContent();
        connectionString.setPassword(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Database").item(0).getTextContent();
        connectionString.setDatabase(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Server").item(0).getTextContent();
        connectionString.setServer(value);
        connectionString.setProvider(ConnectionStringHelper.getProvider(connectionString.getDatabaseType()));


        mapperParameters = new MapperParameters();
        nodeList = document.getElementsByTagName("Mapper");

        value = ((Element) nodeList.item(0)).getElementsByTagName("DriverClass").item(0).getTextContent();
        mapperParameters.setDriverClass(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Dialect").item(0).getTextContent();
        mapperParameters.setDialect(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Provider").item(0).getTextContent();
        mapperParameters.setProvider(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("Isolation").item(0).getTextContent();
        mapperParameters.setIsolation(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("ReleaseMode").item(0).getTextContent();
        mapperParameters.setReleaseMode(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("DefaultSchema").item(0).getTextContent();
        mapperParameters.setDefaultSchema(value);
        value = ((Element) nodeList.item(0)).getElementsByTagName("ProxyFactory").item(0).getTextContent();
        mapperParameters.setProxyFactory(value);


        nodeList = document.getElementsByTagName("Assembly");
        Node node = null;
        assemblies = new HashSet<String>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            node = nodeList.item(i);
            assemblies.add(node.getTextContent());
        }
    }

    /**
     * configure the system with specified parameters.
     *
     * @param providerType
     * @param server
     * @param username
     * @param salt
     * @param database
     * @param databaseVersion
     */
    public void configure(String providerType, String server, String username, String salt, String database, int databaseVersion) {
        Cryptography crypt = new Cryptography();
        String password = crypt.hashTextMD5(salt + username + salt).toUpperCase();

        DatabaseType dt = ConnectionStringHelper.toDatabaseType(providerType);
        setConnectionString(new ConnectionString(dt, username, password, server, database));
        DataConfiguration.databaseVersion = databaseVersion;
    }

    /**
     * The static object that represent a connection string.
     *
     * @return The ConnectionString object.
     */
    public static ConnectionString getConnectionString() {
        return connectionString;
    }

    /**
     * The static object that represent the mapper parameters.
     *
     * @return The MapperParameters object.
     */
    public static MapperParameters getMapperParameters() {
        return mapperParameters;
    }

    /**
     * @param value the connectionString to set
     */
    public static void setConnectionString(ConnectionString value) {
        connectionString = value;
    }

    /**
     * @param value the mapperParameters to set
     */
    public static void setMapperParameters(MapperParameters value) {
        mapperParameters = value;
    }

    /**
     * A collection of assemblies where the model o/r mappings are stored.
     *
     * @return A Set of assemblies names.
     */
    public static Set<String> getAssemblies() {
        if (assemblies == null) {
            assemblies = new HashSet<String>();
        }
        return assemblies;
    }

    /**
     * The version of the database schema.
     *
     * @return An integer representing the database version.
     */
    public static int getDatabaseVersion() {
        return databaseVersion;
    }
}
